import { FC, useEffect, useState, useRef, Key } from 'react'
import {
  connect,
  Dispatch,
  Loading,
  EvaluationStateType,
  PointInfoType,
  PointDetailType,
  history
} from 'umi'
import { findNode, getParentKeys, treeFindPath, getChildKeys } from '@/utils'
import type { RadioChangeEvent } from 'antd'
import type { DataNode, TreeProps } from 'antd/es/tree'
import {
  Tree,
  Breadcrumb,
  Radio,
  Button,
  message,
  Image,
  notification
} from 'antd'
import { Location } from 'history-with-query'
import FilePreview from '@/components/FilePreview'
import PreviewPdf from '@/components/preview-pdf'
import { DownOutlined } from '@ant-design/icons'
import { getStorage } from '@/utils'

import type { NotificationPlacement } from 'antd/es/notification'
import styles from './index.less'

interface IProps {
  evaluationModel: EvaluationStateType
  dispatch: Dispatch
  location: Location
}

const ExpertEvaluation: FC<IProps> = ({
  dispatch,
  evaluationModel,
  location
}) => {
  const { batchCode, type } = location.query as {
    batchCode: string
    type: string
  }
  const { pointInfo, pointDetail, scoreRules, resourceList } = evaluationModel
  const [breadcrumb, setBreadcrumb] = useState<string[]>([])
  const [filePath, setFilePath] = useState<string>('')
  const [defaultSelectedKeys, setDefaultSelectedKeys] = useState<string[]>([])
  const [fileType, setFileType] = useState<string>('')
  const [expandedKeys, setExpandedKeys] = useState<Key[]>([])
  const [isFinish, setIsFinish] = useState<boolean>(false)
  const [modalShow, setModalShow] = useState<boolean>(false)
  const status = useRef<any[]>([])
  const allChildKeys = useRef<string[]>([])

  // 获取材料列表及打分点
  const getPointAndMaterial = (key: string) => {
    const data = findNode(pointInfo, (node: PointInfoType) => {
      return node.code === key
    })
    // 如果不是最里层的节点，直接退出
    if (!data || data?.children) return
    let flag = status.current.every((item) => item.status)
    if (flag) {
      message.warning('所有指标均已打分')
      openNotification('top')
      return
    }
    setDefaultSelectedKeys([key])
    const userCode = getStorage('userCode')
    const temp = treeFindPath(pointInfo, (data) => data.code === key)
    setBreadcrumb(temp)
    getResourceInfo(batchCode, userCode!, key)
    dispatch({
      type: 'evaluationModel/function_getPointInfoByParentCode',
      payload: {
        batchCode: batchCode,
        parentCode: key,
        type
      }
    })
  }

  // 查看具体打分点
  const onSelect: TreeProps['onSelect'] = (selectedKeys) => {
    getPointAndMaterial(selectedKeys[0] as string)
  }

  const getPointInfo = (batchCode: string, type: string) => {
    dispatch({
      type: 'evaluationModel/function_getPointInfo',
      payload: {
        batchCode,
        type
      }
    })
  }

  // 获取打分规则
  const getScoringRules = () => {
    dispatch({
      type: 'evaluationModel/function_getScoringRules',
      payload: {
        ruleCode: '50'
      }
    })
  }

  // 打分
  const handlePoint = (e: RadioChangeEvent, code: string) => {
    const point = e.target.value
    const copyData: PointDetailType[] = JSON.parse(JSON.stringify(pointDetail))
    copyData.forEach((item) => {
      if (item.code === code) {
        item.ruleCode = point
      }
    })
    dispatch({
      type: 'evaluationModel/setState',
      payload: {
        pointDetail: copyData
      }
    })
  }

  const setCurrentPreview = (url: string) => {
    const fileType = url?.substring(url.lastIndexOf('.') + 1)
    if (
      [
        'ppt',
        'pptx',
        'xlsx',
        'docx',
        'xls',
        'doc',
        'zip',
        'rar',
        '7z'
      ].includes(fileType)
    ) {
      window.open(url)
      return
    }
    setFileType(fileType)
    setFilePath(url)
  }

  // 树字段标准化
  const treeFieldsFormat = (arr: PointInfoType[]): DataNode[] => {
    return arr?.map((item) => ({
      title: item.name,
      key: item.code,
      children: item.children ? treeFieldsFormat(item.children) : undefined
    }))
  }

  const openNotification = (placement: NotificationPlacement) => {
    notification.info({
      message: `提示`,
      description: '该账号已评阅完毕,4.5s秒后将返回登录页',
      placement
    })
  }

  // 获取评审资源
  const getResourceInfo = (
    batchCode: string,
    userCode: string,
    questionCode: string
  ) => {
    dispatch({
      type: 'evaluationModel/function_getResourceInfo',
      payload: {
        batchCode,
        userCode,
        questionCode
      },
      callback: (response) => {
        if (!response) {
          setFileType('')
          status.current.forEach((item) => {
            if (item.code == questionCode) {
              item.status = true
            }
          })
          let key = status.current.find((item) => !item.status)?.code
          if (key) {
            setDefaultSelectedKeys([key])
            getPointAndMaterial(key)
          } else {
            message.warning('所有指标的均已评阅完毕')
            setIsFinish(true)
            openNotification('top')
            setTimeout(() => {
              history.replace('/')
            }, 4000)
          }
        }
      }
    })
  }

  const onExpand = (expandedKeys: Key[]) => {
    setExpandedKeys(expandedKeys)
  }

  // 保存打分
  const savePoint = () => {
    // 判断是否打完全部的分
    const verifyResult = pointDetail.every((item) => item.ruleCode)
    if (!verifyResult) {
      message.warning('请打完全部的打分点')
      return
    }
    const json = JSON.stringify(
      pointDetail.map((item) => ({
        questionCode: item.code,
        ruleCode: item.ruleCode
      }))
    )
    dispatch({
      type: 'evaluationModel/function_saveScore',
      payload: {
        batchCode,
        id: resourceList.id,
        json,
        type,
        unitCode: undefined
      },
      callback: (response) => {
        if (response.code == 200) {
          message.success('保存成功')
          getPointAndMaterial(defaultSelectedKeys[0])
        }
      }
    })
  }

  useEffect(() => {
    getPointInfo(batchCode, type)
    getScoringRules()
  }, [])

  // 默认选中第一个非office和压缩文件材料
  useEffect(() => {
    if (!resourceList) return
    let type = ''
    let path = ''
    try {
      resourceList.files?.forEach((item) => {
        if (item.children) {
          item.children.forEach((v: any) => {
            if (
              ![
                'ppt',
                'pptx',
                'xlsx',
                'docx',
                'xls',
                'doc',
                'zip',
                'rar',
                '7z'
              ].includes(v.url.substring(v.url.lastIndexOf('.') + 1))
            ) {
              path = v.url
              type = v.url.substring(v.url.lastIndexOf('.') + 1)
              throw '找到了'
            }
          })
        }
      })
    } catch (err) {
    } finally {
      if (path) {
        setFilePath(path)
        setFileType(type)
      }
    }
  }, [resourceList])

  useEffect(() => {
    if (pointInfo.length) {
      allChildKeys.current = getChildKeys(pointInfo)
      const getAllkeys = (arr: PointInfoType[]) => {
        arr.forEach((item) => {
          if (item.children) {
            getAllkeys(item.children)
          } else {
            status.current = [
              ...status.current,
              { code: item.code, status: false }
            ]
          }
        })
      }

      getAllkeys(pointInfo)
      // 展开tree全部节点
      const expankeys = getParentKeys(pointInfo)
      setExpandedKeys(expankeys)

      setDefaultSelectedKeys([allChildKeys.current[0]])
      getPointAndMaterial(allChildKeys.current[0])
    }
  }, [pointInfo])
  return (
    <>
      <div className={styles['page-wrapper']}>
        <div className={styles['page-left']}>
          <div className={styles['module-title']}>专家评价指标</div>
          <div className={styles['tree-wrapper']}>
            <Tree
              onSelect={onSelect}
              treeData={treeFieldsFormat(pointInfo)}
              selectedKeys={defaultSelectedKeys}
              expandedKeys={expandedKeys}
              onExpand={onExpand}
            />
          </div>
        </div>
        <div className={styles['page-right']}>
          <div className={styles['right-top']}>
            <div className={styles['data-preview']}>
              <div className={styles['module-title']}>
                <span className="title">材料预览</span>
                {fileType == 'pdf' && (
                  <span
                    onClick={() => {
                      setModalShow(true)
                    }}
                  >
                    点击此处弹窗预览pdf
                  </span>
                )}
              </div>
              <div className={styles['module-content']}>
                <div className={styles['preview-wrapper']}>
                  {['jpg', 'png', 'jpeg', 'gif', 'webp'].includes(fileType) ? (
                    <Image src={`${filePath}`} />
                  ) : ['mp4', 'webm', 'ogg'].includes(fileType) ? (
                    <video
                      src={`${filePath}`}
                      controls
                      width="100%"
                      height="100%"
                    >
                      您的浏览器不支持 video 标签。
                    </video>
                  ) : ['pdf'].includes(fileType) ? (
                    <iframe src={filePath} width="100%" height="100%" />
                  ) : ['mp3', 'wav'].includes(fileType) ? (
                    <audio src={filePath} controls muted loop />
                  ) : (
                    <FilePreview fileType={fileType} filePath={filePath} />
                  )}
                </div>
              </div>

              {/* 弹窗预览pdf */}
              <PreviewPdf
                visible={modalShow}
                filePath={filePath}
                hide={() => {
                  setModalShow(false)
                }}
              />
            </div>
            <div className={styles['data-list']}>
              <div className={styles['module-title']}>
                {resourceList.schoolName}材料列表
              </div>
              <div className={styles['module-content']}>
                {resourceList?.files?.map((item) => (
                  <div key={item.type} className={styles['type-item']}>
                    <div className={styles['material-type']}>
                      <span>{item.type}</span>
                      <DownOutlined />
                    </div>
                    <ul className={styles['material-wrapper']}>
                      {item.children?.map((v: any) => (
                        <li
                          key={v.fileName}
                          className={
                            filePath === v.url
                              ? [
                                  `${styles['material-item']}`,
                                  `${styles['active-material']}`
                                ].join(' ')
                              : styles['material-item']
                          }
                          onClick={() => setCurrentPreview(v.url)}
                        >
                          {v.fileName}
                        </li>
                      ))}
                    </ul>
                  </div>
                ))}
              </div>
            </div>
          </div>
          <div className={styles['right-bottom']}>
            <div className={styles['module-title']}>
              <Breadcrumb separator=">">
                {breadcrumb.map((item) => (
                  <Breadcrumb.Item key={item}>{item}</Breadcrumb.Item>
                ))}
              </Breadcrumb>
            </div>

            <div className={styles['module-content']}>
              <div className={styles.breadcrumb}></div>
              <ul className={styles['detail-wrapper']}>
                {pointDetail?.map((item) => (
                  <li key={item.code} className={styles['detail-item']}>
                    <span> {item.name}</span>
                    <Radio.Group
                      onChange={(e) => handlePoint(e, item.code)}
                      value={item.ruleCode}
                      disabled={isFinish}
                    >
                      {scoreRules.map((item) => (
                        <Radio value={item.code} key={item.code}>
                          {item.name}
                        </Radio>
                      ))}
                    </Radio.Group>
                  </li>
                ))}
              </ul>
              <div className={styles['submit-btn']}>
                <div className={styles['code-of-points']}>
                  评分规则: 符合(满分)、基本符合(半分)、不符合(0分)
                </div>
                <Button
                  type="primary"
                  onClick={() => savePoint()}
                  disabled={isFinish}
                >
                  提交
                </Button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}

const mapStateToProps = ({
  evaluationModel,
  loading
}: {
  evaluationModel: EvaluationStateType
  loading: Loading
}) => {
  return {
    evaluationModel,
    evaluationLoding: loading.models.evaluationModel
  }
}

export default connect(mapStateToProps)(ExpertEvaluation)
